# -*- coding: utf-8 -*-
import os
import pandas as pd
import re
import shutil
import json
from openai import OpenAI

# 初始化 DeepSeek 客户端
client = OpenAI(api_key="sk-b6ae6c7c2ae74c01ae26d7d8ae7a503e", base_url="https://api.deepseek.com")

def call_deepseek_api(back, content, option, example):
    """
    调用 DeepSeek API 进行立场分析
    :param back: 背景信息
    :param content: 微博评论内容
    :param option: 可选的 target 选项
    :param example: 示例
    :return: target, stance, opinion
    """
    # 构造 prompt
    prompt = f"""
这件事情的背景是“{back}”你现在要做的任务是对基于该背景的微博内容或评论进行立场分析，现在给你一段微博评论content，你需要输出这段评论所指立场的target是什么，所持有的观点opinion是什么。请注意！有如下要求：
1.立场只有3种选择：支持、反对、中立。不能输出其他的，比如同情、嘲笑等。
2.target指的是这个作者字面上在对谁进行评论？或者说评论的主体/角色。
3.观点的意思就是，为什么对这个target支持或者反对，表示支持或反对的原因，你不能只输出支持或者反对，你必须输出关于支持或者反对的原因。
给个例子：{example}，你需要判断下面这段评论的target、stance、opinion,评论为："{content}"
你需要以json形式输出结果，不能带markdown语法，不需要返回无关信息，也不需要解释，只包含json，key为 target、stance、opinion 这三个
"""
    try:
        # 调用 DeepSeek API
        response = client.chat.completions.create(
            model="deepseek-chat",
            messages=[
                {"role": "system", "content": "你是一个帮助进行立场分析的助手。"},
                {"role": "user", "content": prompt},
            ],
            stream=False
        )
        # 提取返回结果
        result = response.choices[0].message.content.strip()
        print("-------------")
        print(prompt)
        print(result)
        print("-------------")

        # 清理结果中的 markdown 语法
        result = result.replace('```', '').replace('json', '').strip()

        # 解析 JSON
        json_obj = json.loads(result)
        return json_obj['target'], json_obj['stance'], json_obj['opinion']
    except json.JSONDecodeError as je:
        print(f"JSON 解析失败: {je}")
        return 0, 0, 0
    except Exception as e:
        print(f"调用 DeepSeek API 出错: {e}")
        return 0, 0, 0


def call_deepseek_api_for_consistency(target, target2, opinion, opinion2):
    """
    调用 DeepSeek API 判断 target 和 target2 是否一致，以及 opinion 和 opinion2 是否表达相似
    :param target: 原始的 target
    :param target2: 新的 target2
    :param opinion: 原始的 opinion
    :param opinion2: 新的 opinion2
    :return: "一致" 或 "不一致"
    """
    # 构造 prompt
    prompt = f"""
    任务：判断以下两组内容是否一致或相近。如果意思相似或相近，则返回 "一致"；否则返回 "不一致"。

    要求：
    1. 首先判断 target1 和 target2 是否一致或相近。如果不一致，则直接返回 "不一致"。
    2. 如果 target1 和 target2 一致或相近，则进一步判断 opinion1 和 opinion2 是否表达相似。如果相似，则返回 "一致"；如果不相似，则返回 "不一致"。
    3. 意思相似或相近即可，不需要严格每个字都相同。

    输入：
    - target1: {target}
    - target2: {target2}
    - opinion1: {opinion}
    - opinion2: {opinion2}

    请以 JSON 格式返回结果，包含一个字段 "consistency"，值为 "一致" 或 "不一致"。
    """
    try:
        # 调用 DeepSeek API
        response = client.chat.completions.create(
            model="deepseek-chat",
            messages=[
                {"role": "system", "content": "你是一个帮助判断内容一致性的助手。"},
                {"role": "user", "content": prompt},
            ],
            stream=False
        )
        # 提取返回结果
        result = response.choices[0].message.content.strip()
        print("-------------")
        print(prompt)
        print(result)
        print("-------------")

        # 清理结果中的 markdown 语法
        result = result.replace('```', '').replace('json', '').strip()

        # 解析 JSON
        json_obj = json.loads(result)
        return json_obj['consistency']
    except json.JSONDecodeError as je:
        print(f"JSON 解析失败: {je}")
        return "不一致"
    except Exception as e:
        print(f"调用 DeepSeek API 出错: {e}")
        return "不一致"


def remove_hashtags(text):
    """
    移除文本中的 ## 包裹的内容
    :param text: 原始文本
    :return: 清理后的文本
    """
    try:
        text = re.sub(r'##([^#]+)##', '', text)
    except Exception as e:
        text = ""
    return text

def main():
    # 定义背景信息、选项和示例
#     back = """
# 2024年6月，17岁中专生姜萍以第12名成绩入围阿里巴巴全球数学竞赛决赛，引发“草根逆袭”热潮，但随后被质疑作弊。11月3日，组委会调查确认其数学老师王某某在预选赛中违规提供帮助，违反“禁止与他人讨论”规则，二人成绩被取消。阿里巴巴全球数学竞赛组委会公开道歉，承认赛事制度不完善，承诺加强管理，并删除相关视频以消除误导。涟水中专对王某某进行诫勉谈话并取消其评优资格。事件暴露了赛制漏洞、媒体过度渲染及公众对“逆袭”故事的盲目追捧，姜萍则成为舆论风暴的中心，经历从“造神”到“毁神”的跌宕起伏。
# """
#     option = """
# "萝卜快跑","百度","美国","出租车司机","自动驾驶"
# """
#     example = """
# content评论为“捧她上神坛的是你们，拽她下地狱的也是你们。别对我道歉，对姜萍道歉。”， target为“”，opinion为“因为组委会在事件中未能妥善处理，导致姜萍受到不公正对待，应该直接向姜萍道歉。”，stance为“反对”
# """

    # back = """
    # 近日，东南大学土木工程2019级学生徐某因在考研过程中接连被南京大学和兰州大学拒绝录取而引发广泛关注。徐某在2024年考研中初试成绩在南京大学所报考专业排名第一，但在复试中被刷，外界普遍认为这与他的思想品德考核不合格有关。此前，徐某因虐猫行为被举报，并受到警方批评教育，写下悔过书，但其行为仍引发公众强烈不满，认为其性质恶劣，不仅录制虐猫视频，还加入了虐猫组织。南京大学研究生复试细则明确规定，思想品德考核不合格者不予录取，因此南大淘汰徐某有据可依。随后，徐某参加兰州大学调剂复试，但最终也未出现在拟录取名单中，再次被拒。资深媒体人胡锡进对此发声，表示尊重高校决定，但呼吁社会在徐某悔过的前提下给予其更多发展机会。然而，网友普遍不认同胡锡进的观点，认为思想品德在研究生录取中至关重要，对徐某的批评和否定是基于理性和法律的考量。
    # """
    # option = """
    # "萝卜快跑","百度","美国","出租车司机","自动驾驶"
    # """
    # example = """
    # content评论为“老胡啊你天天偷换概念，说这些丧良心话，不怕死了在拔舌地狱轮回啊”， target为“胡锡进”，opinion为“认为胡锡进在偷换概念，说一些没有良心的话”，stance为“反对”
    # """

#     back="""
#     新闻学教授怒怼张雪峰事件的背景主要源于张雪峰在一次直播中的言论。当时，张雪峰在回应一位家长关于孩子报考新闻学专业的咨询时，表示如果孩子非要报新闻学，他甚至会建议“把他打晕”。这一言论迅速引发了争议，并在网络上广泛传播。很快，一些新闻学教授对此表示强烈不满，并站出来怒怼张雪峰。他们认为张雪峰的言论过于偏激，不仅误导了公众，还可能对新闻学专业的学生产生负面影响。其中，重庆大学的新闻学教授张小强就是其中的一位代表，他公开发文批评张雪峰，并强调新闻学的重要性和就业前景。这一事件引起了广泛的关注和讨论，不仅涉及到了专业选择、就业前景等实际问题，也引发了对于言论自由、公众人物责任等议题的思考
# """
#     option="""
#     "张雪峰","新闻学教授","新闻学","国内媒体"
#     """
#     example="""
#     content评论为“哈哈哈，怕招不到学生，以后待遇就差了吧[允悲]”， target为“新闻学教授”，opinion为“认为新闻学教授是怕招不到学生才批评张雪峰”，stance为“反对”
#     """

    back = """
         巴以冲突是中东冲突的核心之一，涉及以色列和巴勒斯坦对同一块土地的排他性主权要求。犹太移民定居点和耶路撒冷地位问题是主要障碍。2024年1月20日，以色列总理内塔尼亚胡表示未承诺建立巴勒斯坦国。1月22日，巴勒斯坦总理阿什提耶强调“两国方案”是国际共识。1月24日，内塔尼亚胡称以色列将继续在加沙的军事行动直至“完全胜利”。3月，以色列没收8平方公里约旦河西岸的巴勒斯坦土地。4月16日，联合国妇女署报告称，新一轮冲突已导致加沙地带超过1万名妇女死亡。
         """
    option="""
    "以色列","锡安复国主义者","巴勒斯坦","哈马斯","美国","西方国家","中国","俄罗斯","伊朗"
    """
    example = """
            content评论为“谁来救救这可怜的孩子啊！以色列快点灭亡吧”， target为“以色列”，opinion为“以色列发动战争让孩子无家可归”，stance为“反对”
            """


    # 文件路径
    from_path = './dic_by/byct.xlsx'  # 输入文件路径
    to_path = "dic_by/byct_cleaned_1.xlsx"  # 备份文件路径

    # 读取需要处理的 Excel 文件
    df = pd.read_excel(from_path)

    # 新增一列 "一致性"，默认值为空
    if "一致性" not in df.columns:
        df["一致性"] = ""

    # 初始化计数器
    count = 0

    # 每隔多少条数据备份一次
    backup_interval = 50

    # 遍历每一行数据
    for index, row in df.iterrows():
        content = remove_hashtags(row["content"])

        # 检查目标、立场和意见是否为空
        if pd.isnull(row["target2"]) and pd.isnull(row["stance2"]) and pd.isnull(row["opinion2"]):
            try:
                if len(content) >= 10:
                    target, stance, opinion = call_deepseek_api(back, content, option, example)
                else:
                    target, stance, opinion = 0, 0, 0
            except Exception as e:
                print(e, end="")
                target, stance, opinion = 0, 0, 0

            print(target, stance, opinion)

            # 更新数据框中的值
            df.at[index, "target2"] = target
            df.at[index, "stance2"] = stance
            df.at[index, "opinion2"] = opinion

            # 判断 target 和 target2 是否一致
            if pd.notnull(row["target"]) and pd.notnull(target):
                consistency = call_deepseek_api_for_consistency(row["target"], target, row["opinion"], opinion)
                df.at[index, "一致性"] = consistency

            # 每处理完一条数据，计数器加1
            count += 1

            # 每处理完10条数据保存一次
            if count % 10 == 0:
                df.to_excel(from_path, index=False)
                print("Saved at index:", index)  # 打印当前索引以便调试

            # 每隔 backup_interval 条数据备份一次
            if count % backup_interval == 0:
                os.makedirs(os.path.dirname(to_path), exist_ok=True)
                shutil.copy(from_path, to_path)
                print("Backup saved at index:", index)  # 打印当前索引以便调试

    # 最后保存一次，确保所有数据都被保存到文件中
    df.to_excel(from_path, index=False)
    print("处理完成，文件已保存")

if __name__ == "__main__":
    main()